package org.six11.ss.server;

import java.math.BigDecimal;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.six11.ss.server.bean.Person;
import org.six11.util.Debug;
import org.six11.util.adt.MultiState;

/**
 * 
 * 
 * @author Gabe Johnson <johnsogg@cmu.edu>
 */
public class Scoreboard {

  public static long SCOREBOARD_REFRESH_TIME = 5 * 60 * 1000;

  protected final static SessionFactory sessionFactory;
  static {
    sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
  }

  private MultiState state;

  /**
   * @param state
   */
  public Scoreboard(MultiState state) {
    this.state = state;
  }

  /**
   * 
   */
  public void go() {
    Timer timer = (Timer) state.getValue(ServerStateNames.TASK_TIMER);
    TimerTask task = new TimerTask() {
      public void run() {
        updateScores();
      }
    };
    timer.schedule(task, 3000, SCOREBOARD_REFRESH_TIME);
    log("Started scoreboard update task.");
  }

  private static void log(String what) {
    Debug.out(">>  Scoreboard", what);
  }

  private static void bug(String what) {
    Debug.out("Scoreboard", what);
  }

  public void updateScores() {
    long start = System.currentTimeMillis();
    Transaction tx = getHibernate().beginTransaction();
    try {
      List<Person> all = getHibernate().createQuery("from Person as person").list();
      for (Person p : all) {
        try {
          BigDecimal raw = (BigDecimal) getHibernate().createSQLQuery(
              "select sum(score) from Score where personID = ?").setInteger(0, p.getId())
              .uniqueResult();
          int res = raw.intValue();
          p.setScore(res);
        } catch (NullPointerException ignore) {
          // this just means the player doesn't have any score entries.
        }
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    } finally {
      tx.commit();
    }
    long elapsed = System.currentTimeMillis() - start;
    bug("Updated scores in " + elapsed + " ms.");
  }

  protected Session getHibernate() {
    return sessionFactory.getCurrentSession();
  }

}
